<template>
  <div style="width: 100%;height: 100%" class="height-box flex-row">
    <div id="businessApp"></div>
    <div style="flex: 1;height:100%;display: flex;justify-content:flex-start;flex-direction: column">
      <div class="span-label" style="border-bottom: 1px solid transparent;border-color: rgb(229,230,235);
padding: 10px;box-sizing: border-box;width: 100%">操作属性
      </div>
      <div style="width: 100%;height: 100%">
        <RightAttr v-if="showAttrHas" :dataBranch="dataSet" @throwBranchName="getBranchName"
        ref="getRightData" ></RightAttr>
      </div>
    </div>

    <addComp v-if="showHover" :client-x="clientX" :client-y="clientY"
             @addNodeBranch="getNodeBranch"></addComp>
  </div>
</template>

<script>
import {Graph} from "@antv/x6";
import dagre from 'dagre'
import "@antv/x6-vue-shape";
import RightAttr from "@/views/systeamSet/moduleManage/components/RightAttr";
import Count from "@/views/systeamSet/moduleManage/components/Count";
import End from "@/views/systeamSet/moduleManage/components/End"
import Modal from '@/views/systeamSet/moduleManage/components/Modal.vue'
import Branch from "@/views/systeamSet/moduleManage/components/Branch";
import addComp from "@/views/systeamSet/moduleManage/components/addComp";
import {createId} from "@/api/public";
import count from "@/views/systeamSet/moduleManage/components/Count";

let graph = null;
let parentDiv = null
let dagreLayout = null
const dir = 'TB' // LR RL TB BT
export default {
  name: "BusinessOrchestration",
  components: {
    addComp,
    RightAttr
  },
  props: {
    tableName: {
      type: String,
      default: ''
    },
    tableId: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      showAttrHas: false,
      dataSet: {},
      showHover: false,
      clientX: 0,
      clientY: 0,
      sourceEl: null,
      targetEl: null,
      branchX: 0,
      branchY: 0,
    }
  },
  mounted() {
    parentDiv = document.querySelector('.height-box')
    graph = new Graph({
      container: document.getElementById("businessApp"),
      resizing: true,
      panning: true,
      width: parentDiv.clientWidth / 1.5,
      height: parentDiv.clientHeight,
      background: {
        color: '#f5f5f5',
      },
      grid: {
        visible: true,
      },
      mousewheel: {
        enabled: true,
        modifiers: ['ctrl', 'meta'],
      },
      autoResize: true,
      connecting: {
        router: "manhattan",
        allowBlank: false,
        allowLoop: false,
        allowNode: false,
        allowEdge: false,
        snap: true,
      }
    });
    Graph.registerVueComponent(
      "count",
      {
        template: `
          <Count/>`,
        components: {
          Count,
        },
      },
      true
    );
    Graph.registerVueComponent(
      "end",
      {
        template: `
          <End/>`,
        components: {
          End,
        },
      },
      true
    );
    Graph.registerVueComponent(
      "modal",
      {
        template: `
          <Modal/>`,
        components: {
          Modal,
        },
      },
      true
    );
    Graph.registerVueComponent(
      "branch",
      {
        template: `
          <Branch/>`,
        components: {
          Branch,
        },
      },
      true
    );
    graph.addNode({
      id: "start",
      shape: "vue-shape",
      x: parentDiv.clientWidth / 1.5 / 2,
      y: 150,
      width: 80,
      height: 40,
      component: "count",
      data: {
        num: 0,
      },
    });
    graph.addNode({
      id: "end",
      shape: "vue-shape",
      x: parentDiv.clientWidth / 1.5 / 2,
      y: 260,
      width: 80,
      height: 40,
      component: "end",
      data: {
        num: 0,
      },
    });
    graph.addEdge({
      source: 'start',
      target: 'end',
      // router: {
      //   name: 'er',
      //   args: {
      //     offset: 'center',
      //   },
      // },
      zIndex: -1,
      attrs: {
        line: {
          targetMarker: {
            name: 'block',
          },
          stroke: "#dedede", // 指定 path 元素的填充色
        },
      }
    })

    graph.on('edge:mouseenter', ({e, edge, view}) => {
      console.log(e, 'e')
      this.sourceEl = edge.source.cell
      this.targetEl = edge.target.cell
      this.showHover = true
      this.clientX = view.targetPoint.x - 15
      this.clientY = view.targetPoint.y
    })
    graph.on('blank:click', ({e, edge, view}) => {
      setTimeout(() => {
        this.showHover = false
      }, 2000)
    })
    graph.on('node:click', ({e, edge, view}) => {
      if (view.cell.data.name == '添加条件') {
        createId().then(result1 => {
          const cell1 = graph.addNode({
            id: result1.data,
            shape: "vue-shape",
            x: this.branchX - 250,
            y: this.branchY,
            width: 200,
            height: 70,
            component: "modal",
            data: {
              branchName: '条件分支',
              id: result1.data,
            },
          });
          this.branchX = this.branchX - 250
          graph.addEdge({
            source: {
              cell: view.cell.id,
              anchor: {
                name: "center",
                args: {
                  dy: -5
                }
              }
            },
            target: result1.data,
            zIndex: -1,
            router: {
              name: 'er',
              args: {
                offset: 'center',
              },
            },
            attrs: {
              line: {
                targetMarker: {
                  name: 'block',
                },
                stroke: "#dedede", // 指定 path 元素的填充色
              },
            }
          })
          graph.addEdge({
            source: {
              cell: result1.data,
              anchor: {
                name: "center",
                args: {
                  dy: -5
                }
              }
            },
            target: this.targetBranchId,
            zIndex: -1,
            router: {
              name: 'er',
              args: {
                offset: 'center',
              },
            },
            attrs: {
              line: {
                targetMarker: {
                  name: 'block',
                },
                stroke: "#dedede", // 指定 path 元素的填充色
              },
            }
          })
        })
      } else {
        this.showAttrHas = false
        setTimeout(()=>{
          this.dataSet = {
            ...view.cell.data,
          }
          this.showAttrHas = true
          this.$nextTick(()=>{
            this.$refs.getRightData.setData(view.cell.data)
          })
        },200)
      }
    })

  },
  methods: {

    // 自动布局
    getNodeBranch(branch) {
      this.showHover = false
      const graphList = graph.getNodes()
      const ind = graphList.findIndex(item => item.id == this.sourceEl)
      if (ind != -1) {
        const obj = graphList[ind].getPosition()
        createId().then(res => {
          if (branch != '条件分支') {
            const cell1 = graph.addNode({
              id: res.data,
              shape: "vue-shape",
              x: this.sourceEl == 'start' ? obj.x - 60 : obj.x,
              y: obj.y + 100,
              width: 200,
              height: 70,
              component: "modal",
              data: {
                id: res.data,
                positX: obj.x - 60,
                positY: obj.y + 150,
                branchName: branch,
                nameLable:branch,
              },
            });
            let keys = Object.keys(graph.getCellById(graphList[ind].id)._model.outgoings)
            let startId = keys.findIndex(item => this.sourceEl == item)
            if (startId != -1) {
              //删除线
              graph.removeCell(graph.getCellById(graphList[ind].id)._model.outgoings[keys[startId]][0])
            }
            graph.addEdge({
              source: this.sourceEl,
              target: res.data,
              zIndex: -1,
              router: {
                name: 'er',
                args: {
                  offset: 'center',
                },
              },
              attrs: {
                line: {
                  targetMarker: {
                    name: 'block',
                  },
                  stroke: "#dedede", // 指定 path 元素的填充色
                },
              }
            })
            const endInd = graphList.findIndex(item => item.id == this.targetEl)
            const cloneArr = graphList.slice(1)
            for (let val of cloneArr) {
              if (graphList[endInd].id == val.id) {
                graph.addEdge({
                  source: res.data,
                  target: val.id,
                  zIndex: -1,
                  router: {
                    name: 'er',
                    args: {
                      offset: 'center',
                    },
                  },
                  attrs: {
                    line: {
                      targetMarker: {
                        name: 'block',
                      },
                      stroke: "#dedede", // 指定 path 元素的填充色
                    },
                  }
                })

              } else {

              }
              this.$nextTick(() => {
                if (graph.isSuccessor(cell1, val, {deep: true})) {
                  const end1 = val.getPosition()
                  val.translate(0, 120)
                }
              })

              continue
            }
          } else {
            graph.addNode({
              id: res.data,
              shape: "vue-shape",
              x: this.sourceEl == 'start' ? obj.x - 10 : obj.x + 50,
              y: obj.y + 130,
              width: 100,
              height: 36,
              component: "branch",
              data: {
                id: res.data,
                name: '添加条件',
                branchName: '添加条件',
              },
            });
            graph.addEdge({
              source: this.sourceEl,
              target: res.data,
              zIndex: -1,
              router: {
                name: 'er',
                args: {
                  offset: 'center',
                },
              },
              attrs: {
                line: {
                  targetMarker: {
                    name: 'block',
                  },
                  stroke: "#dedede", // 指定 path 元素的填充色
                },
              }
            })
            createId().then(result1 => {
              this.branchX = this.sourceEl == 'start' ? obj.x - 200 : obj.x - 150
              this.branchY = obj.y + 210
              const cell1 = graph.addNode({
                id: result1.data,
                shape: "vue-shape",
                x: this.sourceEl == 'start' ? obj.x - 200 : obj.x - 150,
                y: obj.y + 210,
                width: 200,
                height: 70,
                component: "modal",
                data: {
                  id: result1.data,
                  branchName: branch,
                },
              });
              // parent.addChild(childMode1)
              graph.addEdge({
                source: res.data,
                target: result1.data,
                zIndex: -1,
                router: {
                  name: 'er',
                  args: {
                    offset: 'center',
                  },
                },
                attrs: {
                  line: {
                    targetMarker: {
                      name: 'block',
                    },
                    stroke: "#dedede", // 指定 path 元素的填充色
                  },
                }
              })
              let keys = Object.keys(graph.getCellById(graphList[ind].id)._model.outgoings)
              let startId = keys.findIndex(item => this.sourceEl == item)
              if (startId != -1) {
                //删除线
                graph.removeCell(graph.getCellById(graphList[ind].id)._model.outgoings[keys[startId]][0])
              }
              const endInd = graphList.findIndex(item => item.id == this.targetEl)
              const cloneArr = graphList.slice(1)
              for (let val of cloneArr) {
                if (graphList[endInd].id == val.id) {
                  this.targetBranchId = val.id
                  graph.addEdge({
                    source: result1.data,
                    target: val.id,
                    zIndex: -1,
                    router: {
                      name: 'er',
                      args: {
                        offset: 'center',
                      },
                    },
                    attrs: {
                      line: {
                        targetMarker: {
                          name: 'block',
                        },
                        stroke: "#dedede", // 指定 path 元素的填充色
                      },
                    }
                  })

                }

                this.$nextTick(() => {
                  if (graph.isSuccessor(cell1, val, {deep: true})) {
                    const end1 = val.getPosition()
                    console.log(val, 'val-val')
                    console.log(end1, 'end1')
                    val.translate(0, 230)
                  }
                })
                // if(val.id == 'end'){
                //   val.translate(0,250)
                // }
                // else{
                //   val.translate(0,150)
                // }

                continue
              }
            })
            createId().then(result2 => {
              graph.addNode({
                id: result2.data,
                shape: "vue-shape",
                x: this.sourceEl == 'start' ? obj.x + 80 : obj.x + 150,
                y: obj.y + 210,
                width: 200,
                height: 70,
                component: "modal",
                data: {
                  id: result2.data,
                  branchName: '默认条件',
                },
              });
              // parent.addChild(childMode1)
              graph.addEdge({
                source: res.data,
                target: result2.data,
                zIndex: -1,
                router: {
                  name: 'er',
                  args: {
                    offset: 'center',
                  },
                },
                attrs: {
                  line: {
                    targetMarker: {
                      name: 'block',
                    },
                    stroke: "#dedede", // 指定 path 元素的填充色
                  },
                }
              })
              const endInd = graphList.findIndex(item => item.id == this.targetEl)
              const cloneArr = graphList.slice(1)
              for (let val of cloneArr) {
                if (graphList[endInd].id == val.id) {
                  graph.addEdge({
                    source: result2.data,
                    target: val.id,
                    zIndex: -1,
                    router: {
                      name: 'er',
                      args: {
                        offset: 'center',
                      },
                    },
                    attrs: {
                      line: {
                        targetMarker: {
                          name: 'block',
                        },
                        stroke: "#dedede", // 指定 path 元素的填充色
                      },
                    }
                  })

                }
                continue
              }
            })
          }
        })

        // this.$nextTick(()=>{
        //   this.layout()
        // })

      }

    },
    exportToJson() {
      this.getBranchName(this.$refs.getRightData.getThrowTotalData())
      return graph.toJSON()
    },
    getBranchName(obj) {
      const graphList = graph.getNodes()
      const ind = graphList.findIndex(item => item.id == obj.branchId)
      //  实时更新
      if (ind != -1) {
        let nodeType = ''
        if(obj.nameLable == '数据模型'){
          nodeType = 'DATA_MODEL'
        }
        graphList[ind].setData({
          branchName: obj.branchInputName,
          tableName:obj.tableName,
          nodeType,
          ...obj
        })
        console.log(graphList[ind],'graphList[ind]')
      }
    },

    //todo 待优化
    // 自动布局
    layout() {
      const nodes = graph.getNodes()
      const edges = graph.getEdges()
      const g = new dagre.graphlib.Graph()
      g.setGraph({rankdir: dir, nodesep: 16, ranksep: 16})
      g.setDefaultEdgeLabel(() => ({}))

      const width = 260
      const height = 90
      nodes.forEach((node) => {
        g.setNode(node.id, {width, height})
      })

      edges.forEach((edge) => {
        const source = edge.getSource()
        const target = edge.getTarget()
        g.setEdge(source.cell, target.cell)
      })

      dagre.layout(g)

      graph.freeze()

      g.nodes().forEach((id) => {
        const node = graph.getCell(id)
        if (node) {
          const pos = g.node(id)
          node.position(pos.x, pos.y)
        }
      })

      edges.forEach((edge) => {
        const source = edge.getSourceNode()
        const target = edge.getTargetNode()
        const sourceBBox = source.getBBox()
        const targetBBox = target.getBBox()

        console.log(sourceBBox, targetBBox)

        if ((dir === 'LR' || dir === 'RL') && sourceBBox.y !== targetBBox.y) {
          const gap =
            dir === 'LR'
              ? targetBBox.x - sourceBBox.x - sourceBBox.width
              : -sourceBBox.x + targetBBox.x + targetBBox.width
          const fix = dir === 'LR' ? sourceBBox.width : 0
          const x = sourceBBox.x + fix + gap / 2
          edge.setVertices([
            {x, y: sourceBBox.center.y},
            {x, y: targetBBox.center.y},
          ])
        } else if (
          (dir === 'TB' || dir === 'BT') &&
          sourceBBox.x !== targetBBox.x
        ) {
          const gap =
            dir === 'TB'
              ? targetBBox.y - sourceBBox.y - sourceBBox.height
              : -sourceBBox.y + targetBBox.y + targetBBox.height
          const fix = dir === 'TB' ? sourceBBox.height : 0
          const y = sourceBBox.y + fix + gap / 2
          edge.setVertices([
            {x: sourceBBox.center.x, y},
            {x: targetBBox.center.x, y},
          ])
        } else {
          edge.setVertices([])
        }
      })

      graph.unfreeze()
    },
    updateView(json){
      if(json){
        // graph.clearCells()
        console.log(json,'json')
        //更新了
       graph.fromJSON({
          data:{cells:json}
        })
      }
    }


  }
}
</script>

<style scoped>
#businessApp {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

.span-label {
  color: rgb(29, 33, 41);
  font-size: 14px;
  font-weight: 700
}
</style>
